/**
 * Course			:	ISYS2119 - BIS Development 2
 * Assignment		:	03
 * Date due			:	31/08/2012
 * Program 			:	Saigon Bike Rental Catalogue System
 * 
 * Programmer		:	Vuu Ngoc My Linh - s3342015, Tran Thi Van Anh - s3342025
 * 
 * Attributions		:	Lecture slides, Blackboard, Tutorials, Websites (not in reference list document)
 * ====================================================================
 * Description: The main form of the system					
 */

package rmit.ISYS2119.assign03;

import javax.swing.JFrame;

import javax.swing.JComboBox;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.JOptionPane;
import javax.swing.JButton;

import java.awt.Color;

import java.awt.FlowLayout;
import java.awt.Font;

import java.awt.GridLayout;
import java.awt.Container;
import java.awt.BorderLayout;

import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;

public class FormBikeCatalogue extends JFrame implements ActionListener {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	// Static Constants
	public final static String FORM_TITLE = "Saigon Bike Rental Catalogue System";

	// Constants
	// =========

	public final static String[] modelNameStrings = { "Please select",
			"Honda Wave Rs", "Honda Air Blade", "SYM Attila", "SYM Victoria",
			"SYM Magic", "Yamaha Nouvo", "Yamaha Mio", "Yamaha Mio Classico",
			"Yamaha Majestic" };

	public final String[] yearStrings = { "Please select", "2000", "2001",
			"2002", "2003", "2004", "2005", "2006", "2007", "2008", "2009",
			"2010", "2011", "2012" };

	private final int X_LOC = 200;
	private final int Y_LOC = 200;
	private final int WIDTH = 500;
	private final int HEIGHT = 400;

	private final String SAVE_MENU_ITEM_TEXT = "Save Record";
	private final String EXIT_MENU_ITEM_TEXT = "Exit Program";

	private final String DELETE_MENU_ITEM_TEXT = "Delete Record";
	private final String CLEAR_MENU_ITEM_TEXT = "Clear Form";
	private final String SEARCH_MENU_ITEM_TEXT = "Search Record";

	private final String MODEL_REPORT_MENU_ITEM_TEXT = "Bikes Model Name List";
	private final String SPECIFICATIONS_REPORT_MENU_ITEM_TEXT = "Engine Specifications List";
	private final String MODEL_SPECIFICATIONS_REPORT_MENU_ITEM_TEXT = "Model and Specifications List";

	private final String ABOUT_MENU_ITEM_TEXT = "About";

	private final String NEXT_BUTTON_TEXT = ">";
	private final String PREVIOUS_BUTTON_TEXT = "<";
	private final String FIRST_BUTTON_TEXT = "|<";
	private final String LAST_BUTTON_TEXT = ">|";

	private final String SAVE_BUTTON_TEXT = "Save";
	private final String DELETE_BUTTON_TEXT = "Delete";
	private final String SEARCH_BUTTON_TEXT = "Search";

	private final String CLEAR_BUTTON_TEXT = "Clear";
	private final String EXIT_BUTTON_TEXT = "Exit";

	// Attributes

	public int currentIndex;

	public static JComboBox<String> modelNameComboBox;
	public static JComboBox<String> yearComboBox;

	public static JTextField bikeIDTextField;
	public static JTextField engineCapacityTextField;
	public static JTextField descriptionTextField;
	public static JTextField engineSpecificationsTextField;
	public static JTextField rentalCostTextField;

	private JButton nextButton;
	private JButton previousButton;
	private JButton firstButton;
	private JButton lastButton;

	private JButton saveButton;
	private JButton deleteButton;
	private JButton searchButton;

	private JButton clearButton;
	private JButton exitButton;

	private JMenuBar menuBar;

	private JMenu fileMenu;
	private JMenu editMenu;
	private JMenu reportMenu;
	private JMenu helpMenu;

	private JMenuItem saveMenuItem;
	private JMenuItem exitMenuItem;

	private JMenuItem deleteMenuItem;
	private JMenuItem clearMenuItem;
	private JMenuItem searchMenuItem;

	private JMenuItem modelReportMenuItem;
	private JMenuItem specificationsReportMenuItem;
	private JMenuItem modelSpecificationsReportMenuItem;

	private JMenuItem aboutMenuItem;

	public final static String DATA_FILE_NAME = "bikeData.txt";
	static BikeCatalogue bikeCatalogue = new BikeCatalogue(DATA_FILE_NAME);
	BikeDAO dataReader = bikeCatalogue.getDataReader();
	public static ArrayList<Bike> bikesList = bikeCatalogue.getBikes();
	public static Bike bike;

	/**
	 * Test the form
	 * 
	 * @throws Exception
	 */
	public static void main(String[] args) throws Exception {

		// Create GUI form and display at runtime
		// ======================================
		FormBikeCatalogue form = new FormBikeCatalogue();
		form.setVisible(true);
		form.run();
	}

	/**
	 * Constructor
	 */
	public FormBikeCatalogue() {

		// Set form properties
		// ===================
		setTitle(FORM_TITLE);
		setSize(WIDTH, HEIGHT);
		setLocation(X_LOC, Y_LOC);

		// Create menu bar and add menu items
		// ==================================
		menuBar = new JMenuBar();
		setJMenuBar(menuBar);

		fileMenu = new JMenu("File");
		fileMenu.setMnemonic('F');
		menuBar.add(fileMenu);
		fileMenu.add(saveMenuItem = new JMenuItem(SAVE_MENU_ITEM_TEXT, 'S'));
		fileMenu.add(exitMenuItem = new JMenuItem(EXIT_MENU_ITEM_TEXT, 'E'));

		editMenu = new JMenu("Edit");
		editMenu.setMnemonic('E');
		menuBar.add(editMenu);
		editMenu.add(searchMenuItem = new JMenuItem(SEARCH_MENU_ITEM_TEXT, 'S'));
		editMenu.add(clearMenuItem = new JMenuItem(CLEAR_MENU_ITEM_TEXT, 'C'));
		editMenu.add(deleteMenuItem = new JMenuItem(DELETE_MENU_ITEM_TEXT, 'D'));

		reportMenu = new JMenu("Report");
		reportMenu.setMnemonic('R');
		menuBar.add(reportMenu);
		reportMenu.add(modelReportMenuItem = new JMenuItem(
				MODEL_REPORT_MENU_ITEM_TEXT, 'M'));
		reportMenu.add(specificationsReportMenuItem = new JMenuItem(
				SPECIFICATIONS_REPORT_MENU_ITEM_TEXT, 'E'));
		reportMenu.add(modelSpecificationsReportMenuItem = new JMenuItem(
				MODEL_SPECIFICATIONS_REPORT_MENU_ITEM_TEXT, 'N'));

		helpMenu = new JMenu("Help");
		helpMenu.setMnemonic('H');
		menuBar.add(helpMenu);
		helpMenu.add(aboutMenuItem = new JMenuItem(ABOUT_MENU_ITEM_TEXT, 'A'));

		// Create and set components
		// =========================

		// Create panels to hold components
		JPanel northPanel = new JPanel();
		JPanel southPanel = new JPanel(
				new FlowLayout(FlowLayout.CENTER, 10, 20));
		JPanel centerPanel = new JPanel();
		JPanel westPanel = new JPanel();
		JPanel eastPanel = new JPanel();

		// Create the north panel
		// ======================

		// Create the header
		JLabel formHeader = new JLabel();
		Font font = new Font("Arial", Font.BOLD, 15);
		formHeader.setText("Saigon Bike Rental");
		formHeader.setFont(font);
		formHeader.setForeground(Color.BLUE);
		northPanel.add(formHeader, BorderLayout.CENTER);

		// Create the south panel
		// ======================

		// Create panels to hold components
		JPanel navigatorPanel = new JPanel();
		JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 10,
				20));

		// Set layout of this panel
		southPanel.setLayout(new BorderLayout());

		// Create the buttons
		searchButton = new JButton(SEARCH_BUTTON_TEXT);
		buttonPanel.add(searchButton);
		saveButton = new JButton(SAVE_BUTTON_TEXT);
		buttonPanel.add(saveButton);
		clearButton = new JButton(CLEAR_BUTTON_TEXT);
		buttonPanel.add(clearButton);
		deleteButton = new JButton(DELETE_BUTTON_TEXT);
		buttonPanel.add(deleteButton);

		// Create navigators
		firstButton = new JButton(FIRST_BUTTON_TEXT);
		navigatorPanel.add(firstButton);
		previousButton = new JButton(PREVIOUS_BUTTON_TEXT);
		navigatorPanel.add(previousButton);
		nextButton = new JButton(NEXT_BUTTON_TEXT);
		navigatorPanel.add(nextButton);
		lastButton = new JButton(LAST_BUTTON_TEXT);
		navigatorPanel.add(lastButton);
		exitButton = new JButton(EXIT_BUTTON_TEXT);
		navigatorPanel.add(exitButton);

		// Add the navigatorPanel and buttonPanel to this panel.
		southPanel.add(buttonPanel, BorderLayout.NORTH);
		southPanel.add(navigatorPanel, BorderLayout.SOUTH);

		// Create the center panel
		// =======================

		// Set the layout of the panels
		GridLayout centerPanelLayout = new GridLayout(7, 2, 5, 5);

		// Create components and add to panels
		centerPanel.setLayout(centerPanelLayout);

		centerPanel.add(new JLabel("Bike ID:"));
		bikeIDTextField = new JTextField(4);
		centerPanel.add(bikeIDTextField);

		centerPanel.add(new JLabel("Model Name:"));

		
		// Create the combo box, select item at index 0.
		modelNameComboBox = new JComboBox<String>(modelNameStrings);
		modelNameComboBox.setSelectedIndex(0);
		modelNameComboBox.setName("modelNameComboBox");
		centerPanel.add(modelNameComboBox);

		centerPanel.add(new JLabel("Desciption:"));
		descriptionTextField = new JTextField(20);
		centerPanel.add(descriptionTextField);

		centerPanel.add(new JLabel("Engine Capacity (cc):"));
		engineCapacityTextField = new JTextField(3);
		centerPanel.add(engineCapacityTextField);
		engineCapacityTextField.setEditable(false);

		centerPanel.add(new JLabel("Year:"));

		// Create the combo box, select item at index 0.
		yearComboBox = new JComboBox<String>(yearStrings);
		yearComboBox.setSelectedIndex(0);
		centerPanel.add(yearComboBox);

		centerPanel.add(new JLabel("Rental Cost:"));
		rentalCostTextField = new JTextField(20);
		centerPanel.add(rentalCostTextField);

		centerPanel.add(new JLabel("Engine Specification:"));
		engineSpecificationsTextField = new JTextField(20);
		centerPanel.add(engineSpecificationsTextField);

		// Get the container holding the components of this class
		Container con = getContentPane();

		// Set layout of this class
		con.setLayout(new BorderLayout());

		// Add the fieldsPanel and buttonsPanel to this class.
		con.add(northPanel, BorderLayout.NORTH);
		con.add(southPanel, BorderLayout.SOUTH);
		con.add(centerPanel, BorderLayout.CENTER);
		con.add(westPanel, BorderLayout.WEST);
		con.add(eastPanel, BorderLayout.EAST);

		// Register listeners
		// ==================

		// Register action listeners on buttons
		firstButton.addActionListener(this);
		previousButton.addActionListener(this);
		nextButton.addActionListener(this);
		lastButton.addActionListener(this);

		saveButton.addActionListener(this);
		deleteButton.addActionListener(this);
		searchButton.addActionListener(this);

		clearButton.addActionListener(this);
		exitButton.addActionListener(this);

		saveMenuItem.addActionListener(this);
		exitMenuItem.addActionListener(this);

		deleteMenuItem.addActionListener(this);
		clearMenuItem.addActionListener(this);
		searchMenuItem.addActionListener(this);

		modelReportMenuItem.addActionListener(this);
		specificationsReportMenuItem.addActionListener(this);
		modelSpecificationsReportMenuItem.addActionListener(this);

		aboutMenuItem.addActionListener(this);

		// Assign appropriate Engine Capacity when Model Name is selected
		modelNameComboBox.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {

				if (modelNameComboBox.getSelectedItem().equals("Honda Wave Rs")
						|| modelNameComboBox.getSelectedItem().equals(
								"Honda Air Blade")) {
					engineCapacityTextField.setText("100");
				} else if (modelNameComboBox.getSelectedItem().equals(
						"SYM Attila")
						|| modelNameComboBox.getSelectedItem().equals(
								"SYM Victoria")
						|| modelNameComboBox.getSelectedItem().equals(
								"SYM Magic")
						|| modelNameComboBox.getSelectedItem().equals(
								"Yamaha Majestic")) {
					engineCapacityTextField.setText("125");
				} else {
					engineCapacityTextField.setText("115");
				}
			}
		});

		// Exit program when window is closed
		addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				System.exit(0);
			}
		});
	}

	// Get all records from the text file, extract them into arraylist when the
	// form first loads
	public void run() throws Exception {
		try {

			bike = dataReader.next();
			while (bike != null) {
				bikesList.add(bike);
				bike = dataReader.next();
			}

			// Show the bikes list
			listBikes(bikesList); // this line is to test the bikes loading
			currentIndex = 0;
			loadBike(currentIndex);
		} catch (Exception e) {

			System.err.println(e.getMessage());
		}
	}

	// Load the bike based on the BikeID
	public static void loadBike(int index) {
		String format = String.format("%04d", bikesList.get(index).getBikeId());
		bikeIDTextField.setText(String.format(format, bikesList.get(index)
				.getBikeId()));
		String modelName = bikesList.get(index).getModelName();
		switch (modelName) {
		case "Honda Wave Rs":
			modelNameComboBox.setSelectedIndex(1);
			break;
		case "Honda Air Blade":
			modelNameComboBox.setSelectedIndex(2);
			break;
		case "SYM Attila":
			modelNameComboBox.setSelectedIndex(3);
			break;
		case "SYM Victoria":
			modelNameComboBox.setSelectedIndex(4);
			break;
		case "SYM Magic":
			modelNameComboBox.setSelectedIndex(5);
			break;
		case "Yamaha Nouvo":
			modelNameComboBox.setSelectedIndex(6);
			break;
		case "Yamaha Mio":
			modelNameComboBox.setSelectedIndex(7);
			break;
		case "Yamaha Mio Classico":
			modelNameComboBox.setSelectedIndex(8);
			break;
		case "Yamaha Majestic":
			modelNameComboBox.setSelectedIndex(9);
			break;
		default:
			modelNameComboBox.setSelectedIndex(0);
			break;
		}
		descriptionTextField.setText(bikesList.get(index).getDescription());
		engineCapacityTextField.setText(bikesList.get(index)
				.getEngineCapacity() + "");
		yearComboBox.setSelectedIndex(index + 1);
		rentalCostTextField.setText(bikesList.get(index).getRentalCost() + "");

		String specShow = bikesList.get(index).getSpecifications().get(0)
				.getSpecification();
		for (int j = 1; j < bikesList.get(index).getSpecifications().size(); j++) {
			specShow = specShow
					+ ","
					+ bikesList.get(index).getSpecifications().get(j)
							.getSpecification();
		}
		engineSpecificationsTextField.setText(specShow);
		// }

	}

	/**
	 * 
	 * Test by listing the bikes
	 */
	private void listBikes(ArrayList<Bike> bikesList) {

		Bike bike;
		for (int i = 0; i < bikesList.size(); i++) {
			bike = bikesList.get(i);
			String format = String.format("%04d", bike.getBikeId());
			
			String spec = "";
			for (int j = 0; j < bike.getSpecifications().size(); j++) {
				spec = spec
						+ bike.getSpecifications().get(j).getSpecification()
						+ ",";
			}
			System.out.println(i + 1 + ". "
					+ String.format(format, bike.getBikeId()) + ", "
					+ bike.getModelName() + ", " + bike.getDescription() + ", "
					+ bike.getEngineCapacity() + ", " + bike.getRentalCost()
					+ ", " + spec);
		}
	}

	/**
	 * 
	 */
	public void actionPerformed(ActionEvent ae) {

		try {
			switch (ae.getActionCommand()) {

			case SAVE_MENU_ITEM_TEXT:
				ButtonFunctionality.save(bikesList);
				break;
			case EXIT_MENU_ITEM_TEXT:
				ButtonFunctionality.exit();
				break;

			case DELETE_MENU_ITEM_TEXT:
				ButtonFunctionality.delete(bikesList);
				break;
			case CLEAR_MENU_ITEM_TEXT:
				ButtonFunctionality.clearConfirmation();
				break;
			case SEARCH_MENU_ITEM_TEXT:
				
				ButtonFunctionality.search(bikesList);
				break;

			case MODEL_REPORT_MENU_ITEM_TEXT:
				ButtonFunctionality.generateModelReport(bikesList);
				this.dispose();
				break;
			case SPECIFICATIONS_REPORT_MENU_ITEM_TEXT:
				ButtonFunctionality.generateSpecificationReport(bikesList);
				this.dispose();
				break;
			case MODEL_SPECIFICATIONS_REPORT_MENU_ITEM_TEXT:
				ButtonFunctionality.generateModelSpecificationReport(bikesList);
				this.dispose();
				break;
			case ABOUT_MENU_ITEM_TEXT:
				ButtonFunctionality.openAboutForm(bikesList);
				break;

			case FIRST_BUTTON_TEXT:
				ButtonFunctionality.first(this);
				break;
			case PREVIOUS_BUTTON_TEXT:
				ButtonFunctionality.previous(this);
				break;
			case NEXT_BUTTON_TEXT:
				ButtonFunctionality.next(this);
				break;
			case LAST_BUTTON_TEXT:
				ButtonFunctionality.last(this);
				break;

			case SAVE_BUTTON_TEXT:
				ButtonFunctionality.save(bikesList);
				break;
			case DELETE_BUTTON_TEXT:
				ButtonFunctionality.delete(bikesList);
				break;
			case SEARCH_BUTTON_TEXT:
				ButtonFunctionality.search(bikesList);
				break;

			case CLEAR_BUTTON_TEXT:
				ButtonFunctionality.clearConfirmation();
				break;
			case EXIT_BUTTON_TEXT:
				ButtonFunctionality.exit();
				break;

			default:
				throw new Exception("Unknown event!");
			}
		} catch (Exception e) {
			JOptionPane.showMessageDialog(this, e.getMessage(), "Error!",
					JOptionPane.ERROR_MESSAGE);
			e.printStackTrace();
		}

	}

}